package com.credithc.eagleeye.demo.web;
import com.alibaba.fastjson.JSON;
import com.credithc.eagleeye.demo.entity.DemoUser;
import com.credithc.eagleeye.demo.feign.DemoServiceUrlClient;
import com.credithc.eagleeye.demo.feign.DemoDubboServiceClient;
import com.credithc.eagleeye.demo.feign.DemoServiceRibbonClient;
import com.credithc.eagleeye.demo.service.DemoService;
import com.credithc.eagleeye.demo.service.impl.HttpClientServiceImpl;
import com.credithc.eagleeye.demo.service.impl.RabbitMqServiceImpl;
import com.credithc.eagleeye.demo.vo.ResponseVo;
import com.credithc.eagleeye.demo.vo.UserVo;
import com.credithc.eagleeye.plugins.annotation.EagleEyeIgnoreAnnotation;
import com.credithc.eagleeye.plugins.thread.EagleEyeCallable;
import com.credithc.eagleeye.plugins.thread.EagleEyeRunnable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
 * 描 述: <br/>
 * 作 者: zhangjin<br/>
 * 创 建：2018年02月07日<br/>
 * 版 本：v1.0.0<br>
 * <p>
 * 历 史: (版本) 作者 时间 注释 <br/>
 */
@SuppressWarnings("AlibabaThreadPoolCreation")
@Slf4j
@Controller
public class DemoController {
    @Autowired
    private DemoService demoService;
    @Autowired
    private DemoServiceRibbonClient demoServiceRibbonClient;
    @Autowired
    private DemoDubboServiceClient demoDubboServiceClient;
    @Autowired
    private RabbitMqServiceImpl rabbitMqService;
    @Autowired
    private HttpClientServiceImpl httpClientService;
    @Autowired
    RestTemplate restTemplate;
    @Autowired
    DemoServiceUrlClient demoServiceUrlClient;

    @ResponseBody
    @RequestMapping(value = "/saveUser", method = RequestMethod.POST)
    public int saveUser(@RequestBody DemoUser demoUser) {
        return demoService.saveUser(demoUser);
    }

    @ResponseBody
    @RequestMapping(value = "/queryUser", method = RequestMethod.GET)
    public Object queryUser(@RequestParam(name = "pageNum", required = false, defaultValue = "1") int pageNum,
                            @RequestParam(name = "pageSize", required = false, defaultValue = "10") int pageSize) {
        return demoService.queryUser(pageNum, pageSize);
    }

    @ResponseBody
    @RequestMapping(value = "/queryUserIgnoreEagleEye", method = RequestMethod.GET)
    @EagleEyeIgnoreAnnotation
    public Object queryUserIgnoreEagleEye(@RequestParam(name = "pageNum", required = false, defaultValue = "1") int pageNum,
                            @RequestParam(name = "pageSize", required = false, defaultValue = "10") int pageSize) {
        return demoService.queryUser(pageNum, pageSize);
    }

    @ResponseBody
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello(String name) {
        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("start");
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("end");
            }
        };
        for(int i = 0; i < 10; i++) {
            threadPool.execute(new EagleEyeRunnable(runnable));
        }
        return "hello:" + name;
    }

    @ResponseBody
    @RequestMapping(value = "/hello2", method = RequestMethod.GET)
    public String hello2(String name) throws ExecutionException, InterruptedException {
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("start");
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("end");
                return "call stop";
            }
        };
        EagleEyeCallable<String> eagleEyeCallable = new EagleEyeCallable<>(callable);
        Future<String> future = threadPool.submit(eagleEyeCallable);
        String ret = future.get();
        return "hello:" + ret;
    }

    @ResponseBody
    @RequestMapping(value = "/invokeFeignRibbonGet", method = RequestMethod.GET)
    public String invokeFeignRibbonGet(String name) {
        String hello = demoServiceRibbonClient.hello(name);
        return "invokeFeignRibbonGet:" + hello;
    }

    @ResponseBody
    @RequestMapping(value = "/invokeFeignRibbonPost", method = RequestMethod.GET)
    public String invokeFeignRibbonPost(String name) {
        UserVo userVo = new UserVo();
        userVo.setName("zhangsan");
        userVo.setAge("12");
        ResponseVo<UserVo> responseVo = demoServiceRibbonClient.hello2(userVo);
        return responseVo.toString();
    }


    @ResponseBody
    @RequestMapping(value = "/invokeDubboClient", method = RequestMethod.GET)
    public String invokeDubboClient(String name) {
        String hello = demoDubboServiceClient.hello(name);
        return "invokeDubboClient:" + hello;
    }

    @ResponseBody
    @RequestMapping(value = "/invokeDubboClientTimeout", method = RequestMethod.GET)
    public String invokeDubboClientTimeout(String name) {

        String hello = demoDubboServiceClient.hello(name);
        return "invokeDubboClient:" + hello;
    }

    @ResponseBody
    @RequestMapping(value = "/getParameter", method = RequestMethod.GET)
    public String getParameter(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        System.out.println(JSON.toJSONString(parameterMap));
        return parameterMap.toString();
    }

    @ResponseBody
    @RequestMapping(value = "/postParameter", method = RequestMethod.POST)
    public String postParameter(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        System.out.println(JSON.toJSONString(parameterMap));
        return JSON.toJSONString(parameterMap);
    }

    @ResponseBody
    @RequestMapping(value = "/sendRabbitMq", method = RequestMethod.POST)
    public String sendRabbitMq(@RequestBody UserVo userVo) {
        rabbitMqService.send(userVo);
        return JSON.toJSONString(userVo);
    }

    @ResponseBody
    @RequestMapping(value = "/sendRabbitMq2", method = RequestMethod.POST)
    public String sendRabbitMq2(@RequestBody UserVo userVo) {
        rabbitMqService.send(userVo);
        rabbitMqService.send(userVo);
        return JSON.toJSONString(userVo);
    }

    @ResponseBody
    @RequestMapping(value = "/restTemplate", method = RequestMethod.GET)
    public String restTemplate() {
        String result = restTemplate.getForObject("http://nacos-discovery-server/hello?name=didi", String.class);
        return result;
    }
    @ResponseBody
    @RequestMapping(value = "/testHttpClient", method = RequestMethod.GET)
    public String testHttpClient() {
        String result = httpClientService.httpGet("http://www.baidu.com/xx?xxx=xxx");
        return result;
    }
    @ResponseBody
    @RequestMapping(value = "/invokeFeignUrlGet", method = RequestMethod.GET)
    public String invokeFeignUrlGet(String name) {
        String hello = demoServiceUrlClient.hello(name);
        return "invokeFeignUrlGet:" + hello;
    }
}
